#ifndef _TSM_FACE_RECOG_H_
#define _TSM_FACE_RECOG_H_

#include <stdbool.h>
#include "face_result.h"
#include "net_param.h"
#include "human_pose_type.h"
#include "sl3d.h"
#ifdef __cplusplus
extern "C" {
#endif

#define MAX_FACE_NUM            5

#define MATCH_TOP_NUM  1  /*  */

typedef struct 
{    
    float   facedetect_thres;       /* face detect */
    float   occusion_thres;         /* occusion */
    float   maskclassify_thres;     /* maskclassify */
    float   living2d_thres;         /* 2d */
    float   living3d_thres;         /* 3d */
    float   headpose_thres[3];       /* head pose */
} algo_faceparam_t;

typedef struct {
    void *img_l;        //3DE left input image
    void *img_r;        //3DE right input image
    void *depth_input;  //depthMap input enable when config.do_depth = 0 and depth_input vaild
} algo_sl3d_input_t;


typedef struct {
    // the range of x and y is 0.0f~1.0f
    float xmin;
    float ymin;
    float xmax;
    float ymax;
    float score;
    float class_id;
} algo_facebox_t;

typedef struct {
    int len;          //the length of every face feature vector
    int16_t *vector;  //size = nFace * len * sizeof(int16_t)
} algo_facefeature_t;

typedef struct {
    bool fuzzy;
    bool glasses;
    bool cover;
    float pose[3]; //roll pitch yaw
    bool bad_posture;
} algo_facequality_t;

typedef struct {
    int   facenum;                       //detect face number 
    bool  live2d[MAX_FACE_NUM];          //live2d is fake
    bool  liveRGB[MAX_FACE_NUM];          //liveRGB is fake
    bool  live3d[MAX_FACE_NUM];          //live3d is fake
    float live2d_score[MAX_FACE_NUM];    //live2d fake score
    float liveRGB_score[MAX_FACE_NUM];    //liveRGB fake score
    float live3d_score[MAX_FACE_NUM];    //live3d fake score
    float occusion_score[MAX_FACE_NUM];  //occusion score

    algo_facefeature_t feature;         //face feature
    algo_facebox_t     facebox[MAX_FACE_NUM];        //face box   size = nFace * sizeof(algo_facebox_t)
    algo_facequality_t quality[MAX_FACE_NUM];        //face quality
    
} algo_facereco_result_t;


typedef enum {
    IMAGE_TYPE_RGB = 0,
    IMAGE_TYPE_GRAY,
} algo_imagetype_e;

typedef enum {
    LOCK_APP = 0,
    GUARD_APP,
} algo_apptype_e;


typedef struct
{
    bool            detect_nir;
    bool            do_depthmap;
    bool            only_dispmap;  
    bool            detect_vis;
    bool            live_nir;
    bool            live_3d;
    bool            live_vis;
    bool            face_attr;
    bool            recog;
    bool            head_pose;
    bool            cover;
    bool            mask;

    algo_imagetype_e recog_img_type;
    algo_apptype_e   recog_app_type;
}algo_facereco_config_t;


typedef struct
{
	int			feat_len;  /* feature vector size */
	int 		pool_num;  /* number of feature vector */
	float		threshold;
	int16_t *	feat;      /* feature buffer */
	int16_t	* 	pool;      /* the feature pool*/
	/* search */
	int 		max_valid_num;
	int			max_div2_search;
	/* calculate score */
	int 		Qfeat;
}tsm_match_param;

typedef struct
{
	bool		result_valid;
	int			vaild_num;
	int			idx[MATCH_TOP_NUM];
	int16_t		score[MATCH_TOP_NUM];		/*< Q15 */
	uint32_t    match_words;         /* Number of words used for matching*/      
	uint32_t    *bitBool;
	int          error_code;
}tsm_match_result;
/**
 * @brief Initialization
 * @param face_vec_num: face featrue vector number need be compared to the recognized face featrue vector
 * @param face_vec: the recognized face featrue vector pool
 *          if the length of one feature vector is L, and face_vec_num is N
 *          then the size of face_vec should be N * L * sizeof(int16_t)
 * @param ConvertBoxFun_t : convert face box coordinate for live detection
 */ 
int tsm_algo_face_proc_init(int h, int w, void *weight);


/**
 * @brief 
 * 
 * @param param 
 * @return int 
 */
int tsm_algo_set_face_param(algo_faceparam_t * param);

/**
 * @brief 
 * 
 * @param param 
 * @return int 
 */
int tsm_algo_get_face_param(algo_faceparam_t * param);

/**
 * @brief 
 * 
 * @param img 
 * @param img_3d 
 * @param config 
 * @return algo_facereco_result_t* 
 */
algo_facereco_result_t *tsm_algo_face_recog( void *img, algo_sl3d_input_t *img_3d, algo_facereco_config_t * config);

/**
 * @brief 
 * 
 * @param match_param 
 * @return tsm_match_result* 
 */
tsm_match_result * tsm_algo_run_match(tsm_match_param *match_param);
#ifdef __cplusplus
}
#endif

#endif

